package cn.tinkling.handlers;

import java.awt.Toolkit;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Set;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.wb.swt.ResourceManager;
import org.eclipse.wb.swt.SWTResourceManager;

import cn.tinkling.Constants;

public class LintResultDialog extends Dialog implements Constants {

	HashMap<String, LinkedList<String>> mLintResultsMap;

	protected LintResultDialog(Shell parentShell, HashMap<String, LinkedList<String>> results) {
		super(parentShell);

		mLintResultsMap = new HashMap<String, LinkedList<String>>(results);
	}

	@Override
	protected void configureShell(Shell shell) {
		super.configureShell(shell);

		shell.setText("Android Resourses Cleaner");
		shell.setImage(ResourceManager.getPluginImage("cn.tinkling", "icons/clean_16.png"));

		int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
		int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;

		int width = 500;
		int height = 600;
		shell.setSize(width, height);
		shell.setLocation((screenWidth - width) >> 1, (screenHeight - height) >> 1);
	}

	@Override
	protected Control createDialogArea(Composite parent) {
		Composite composite = (Composite) super.createDialogArea(parent);
		GridLayout gridLayout = (GridLayout) composite.getLayout();
		gridLayout.horizontalSpacing = 0;
		gridLayout.verticalSpacing = 0;
		gridLayout.marginWidth = 0;
		gridLayout.marginHeight = 0;

		Composite headerComposite = new Composite(composite, SWT.NONE);
		headerComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT));
		GridLayout gl_headerComposite = new GridLayout(2, false);
		gl_headerComposite.marginHeight = 10;
		gl_headerComposite.marginWidth = 10;
		gl_headerComposite.horizontalSpacing = 50;
		headerComposite.setLayout(gl_headerComposite);
		headerComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		Composite titleComposite = new Composite(headerComposite, SWT.NONE);
		titleComposite.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
		titleComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT));
		GridLayout gl_titleComposite = new GridLayout(1, false);
		gl_titleComposite.verticalSpacing = 12;
		titleComposite.setLayout(gl_titleComposite);

		Label title = new Label(titleComposite, SWT.NONE);
		title.setFont(SWTResourceManager.getFont("Microsoft YaHei UI", 12, SWT.BOLD));
		title.setText("Unused Resources Check Result");
		title.setBackground(SWTResourceManager.getColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT));

		Label subtitle = new Label(titleComposite, SWT.NONE);
		subtitle.setFont(SWTResourceManager.getFont("Microsoft YaHei UI", 10, SWT.NORMAL));
		subtitle.setText("   \u4EE5\u4E0B\u8D44\u6E90\u5C06\u4F1A\u88AB\u5220\u9664\uFF08\u6CE8\u610F\uFF1A\u6CA1\u6709\u4FDD\u5B58\u7684\u5185\u5BB9\u4E5F\u5C06\u4F1A\u88AB\u6E05\u9664\uFF09");
		subtitle.setBackground(SWTResourceManager.getColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT));

		Label icon = new Label(headerComposite, SWT.NONE);
		icon.setImage(ResourceManager.getPluginImage("cn.tinkling", "icons/clean_48.png"));
		icon.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1));
		icon.setBackground(SWTResourceManager.getColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT));

		Label separator1 = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
		separator1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		TreeViewer treeViewer = new TreeViewer(composite, SWT.MULTI);
		Tree tree = treeViewer.getTree();
		tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

		treeViewer.setContentProvider(new ContentProvider());
		treeViewer.setLabelProvider(new LintLabelProvider());

		treeViewer.setInput(getTreeElements());

		Label separator2 = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
		separator2.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		return composite;
	}

	private void addElements(TreeElement root, Collection<String> textList) {
		if (textList == null || textList.size() == 0)
			return;

		int i = 0;
		TreeElement[] children = new TreeElement[textList.size()];
		for (String v : textList) {
			children[i++] = new TreeElement(root, v);
		}

		root.children = children;
	}

	private TreeElement getTreeElements() {
		TreeElement root = new TreeElement("res");

		HashMap<String, LinkedList<String>> results = mLintResultsMap;
		LinkedList<String> fileList = results.remove(LINT_RESULT_TYPE_FILES);
		Set<String> keySet = results.keySet();

		int size = 0;
		if (fileList != null)
			size++;
		if (keySet.size() > 0)
			size++;

		if (size == 0)
			return null;

		TreeElement[] resTypeElements = new TreeElement[size];

		if (fileList != null) {
			TreeElement fileParentElement = new TreeElement(root, LINT_RESULT_TYPE_FILES);
			addElements(fileParentElement, fileList);
			resTypeElements[0] = fileParentElement;
		}

		if (keySet.size() > 0) {
			TreeElement valueParentElement = new TreeElement(root, LINT_RESULT_TYPE_VALUES);
			addElements(valueParentElement, keySet);

			TreeElement[] valueTypes = valueParentElement.children;
			for (TreeElement valueType : valueTypes) {
				addElements(valueType, results.get(valueType.text));
			}

			resTypeElements[size > 1 ? 1 : 0] = valueParentElement;
		}

		root.children = resTypeElements;

		return root;
	}

	class ContentProvider implements ITreeContentProvider {

		@Override
		public Object[] getElements(Object inputElement) {
			if (inputElement instanceof TreeElement) {
				return ((TreeElement) inputElement).children;
			}

			return null;
		}

		@Override
		public Object[] getChildren(Object parentElement) {
			if (parentElement instanceof TreeElement) {
				return ((TreeElement) parentElement).children;
			}

			return null;
		}

		@Override
		public Object getParent(Object element) {
			return ((TreeElement) element).parent;
		}

		@Override
		public boolean hasChildren(Object element) {
			Object[] p = getChildren(element);

			return p != null && getChildren(element).length > 0;
		}

		@Override
		public void dispose() {
		}

		@Override
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		}
	}

	class LintLabelProvider extends LabelProvider {

		private Image activityObj = ResourceManager.getPluginImage("cn.tinkling", "/icons/obj16/activity_obj.png");
		private Image xmlObj = ResourceManager.getPluginImage("cn.tinkling", "/icons/obj16/xml_obj.gif");
		private Image elementObj = ResourceManager.getPluginImage("cn.tinkling", "/icons/obj16/element_obj.gif");
		private Image fileObj = ResourceManager.getPluginImage("cn.tinkling", "/icons/obj16/file_obj.gif");
		private Image jpgObj = ResourceManager.getPluginImage("cn.tinkling", "icons/obj16/jpg_obj.png");
		private Image pngObj = ResourceManager.getPluginImage("cn.tinkling", "icons/obj16/png_obj.png");
		private Image mediaObj = ResourceManager.getPluginImage("cn.tinkling", "icons/obj16/media_obj.png");

		@Override
		public String getText(Object element) {
			return ((TreeElement) element).text;
		}

		@Override
		public Image getImage(Object element) {
			String text = getText(element);

			if (LINT_RESULT_TYPE_FILES.equals(text) || LINT_RESULT_TYPE_VALUES.equals(text)) {
				return activityObj;
			} else if (text.endsWith(".xml") || text.endsWith(".XML")) {
				return xmlObj;
			} else if (text.matches("R\\.(\\w)+\\.(\\w)+")) {
				return elementObj;
			} else if (text.endsWith(".jpg") || text.endsWith(".JPG")) {
				return jpgObj;
			} else if (text.endsWith(".png") || text.endsWith(".PNG")) {
				return pngObj;
			} else if (text.endsWith(".mp3") || text.endsWith(".MP3") || text.endsWith(".ogg") || text.endsWith(".OGG")) {
				return mediaObj;
			}

			return fileObj;
		}
	}

	static class TreeElement {
		TreeElement parent;
		String text;
		TreeElement[] children;

		TreeElement() {
		}

		public TreeElement(TreeElement parent, String text, TreeElement[] children) {
			this.parent = parent;
			this.text = text;
			this.children = children;
		}

		public TreeElement(TreeElement parent, String text) {
			this(parent, text, null);
		}

		public TreeElement(String text, TreeElement[] children) {
			this(null, text, children);
		}

		public TreeElement(String text) {
			this(null, text, null);
		}

	}

}
